package main

import (
	"bufio"
	"fmt"
	"github.com/xuri/excelize/v2"
	"go_learn/demo/entity"
	"go_learn/utils"
	"log"
	"os"
	"sort"
	"strconv"
	"strings"
	"time"
)

var (
	line   = 1
	maxCol = "" // 最大col
	ex     = 4  // excel额外行
	excel  = "" // excel位置
	rSheet = ""
	wSheet = "打卡日报"
)

var colArr []string
var names map[string]bool = map[string]bool{"1": false}

func init() {
	excel = getInput("请输入excel名称，需带文件后缀(默认为report.xlsx):")
	if excel == "" {
		excel = "report.xlsx"
	}
	rSheet = getInput("请输入页签名(默认为data)")
	if rSheet == "" {
		rSheet = "data"
	}
}

// 姓名纵向排布
func main() {

	fmt.Println("生成excel。。。")
	rows := readExcel()
	if rows == nil {
		return
	}
	makeRow(rows)
	days := makeDate(rows)
	reports := makeReport(days, rows)
	makeExcel(reports)
	fmt.Println("生成完毕@_@")

	getInput("按任意建退出...")
}

func getInput(s string) string {
	fmt.Println(s)
	in := bufio.NewReader(os.Stdin)
	readLine, _, err := in.ReadLine()
	if err != nil {
		return err.Error()
	}
	return string(readLine)
}

// 生成Row
func makeRow(rows [][]string) {
	for _, row := range rows {
		name := row[1]
		if names[name] {
			continue
		}
		names[name] = true
	}
	max := len(names)
	max = 4 * (max + 1)
	prefix := ""
	l := 0
	for i := 0; i <= max; i++ {
		if i >= 26*(l+1) {
			prefix = string(rune(l + 65))
			l++
		}
		col := prefix + string(rune(i+65-26*l))
		colArr = append(colArr, col)
	}
	maxCol = colArr[len(colArr)-1:][0]
}

// 生成报告数据
func makeReport(days entity.Days, rows [][]string) []entity.Report {
	var pd = make(map[string][]entity.Person)
	for _, row := range rows {
		dateWeek := row[0]
		fields := strings.Fields(dateWeek)
		date := fields[0]
		name := row[1]
		enName := row[2]
		startTime := row[6]
		endTime := row[7]
		holiday := row[11]
		desc := row[12]
		person := entity.Person{
			Name:    name,
			EnName:  enName,
			Start:   startTime,
			End:     endTime,
			Desc:    desc,
			Holiday: holiday,
		}
		persons, ok := pd[date]
		if !ok {
			persons = []entity.Person{}
		}
		pd[date] = append(persons, person)
	}

	var reports []entity.Report
	for _, day := range days {
		if day.Time == 0 {
			continue
		}
		persons := pd[day.Date]
		oName := utils.DeepCopy(names)
		for _, person := range persons {
			delete(oName, person.Name)
		}
		if len(oName) > 0 {
			for name, ok := range oName {
				if ok {
					persons = append(persons, entity.Person{
						Name:    name,
						EnName:  "",
						Start:   "-",
						End:     "-",
						Desc:    "",
						Holiday: "",
					})
				}
			}
		}

		sort.Sort(entity.Persons(persons))
		report := entity.Report{
			Date:    day.Date,
			Week:    day.Week,
			Persons: persons,
		}
		reports = append(reports, report)
	}
	return reports
}

// 读取Excel
func readExcel() [][]string {
	file, err := excelize.OpenFile(excel)
	if err != nil {
		log.Fatal(err)
		return nil
	}

	defer func() {
		err := file.Close()
		if err != nil {
			log.Fatal(err)
		}
	}()

	// 获取 Sheet1 上所有单元格
	rows, err := file.GetRows(rSheet)
	if err != nil {
		log.Fatal(err)
		return nil
	}
	return rows[ex:]
}

// 生成日期
func makeDate(rows [][]string) entity.Days {
	// 日期
	days := make(map[string]string)
	for _, row := range rows {
		dateWeek := row[0]
		rows := strings.Fields(dateWeek)
		date := rows[0]
		week := rows[1]
		if _, ok := days[date]; !ok {
			days[date] = week
		}
	}

	dateList := make(entity.Days, 32)
	i := 0
	for date, week := range days {
		parse, err := time.Parse("2006/01/02", date)
		if err != nil {
			continue
		}
		if parse.Unix() == 0 {
			continue
		}
		dateList[i] = entity.Day{
			Time: parse.Unix(),
			Date: date,
			Week: week,
		}
		i++
	}
	other := 0
	for _, day := range dateList {
		if day.Time == 0 {
			other++
		}
	}
	dateList = append(dateList[:len(dateList)-other])
	sort.Sort(dateList)
	return dateList
}

// 生成Excel
func makeExcel(reports []entity.Report) {
	file, _ := excelize.OpenFile(excel)
	defer func() {
		err := file.Close()
		if err != nil {
			log.Fatal(err)
		}
	}()
	index := file.NewSheet(wSheet)
	file.SetActiveSheet(index)

	style, err := file.NewStyle(&excelize.Style{
		Alignment: &excelize.Alignment{
			Horizontal: "center",
			Vertical:   "center",
		},
		Border: []excelize.Border{
			{Type: "left", Color: "6e7ea", Style: 1},
			{Type: "top", Color: "e6e7ea", Style: 1},
			{Type: "bottom", Color: "e6e7ea", Style: 1},
			{Type: "right", Color: "e6e7ea", Style: 1},
		},
		Fill: excelize.Fill{Type: "gradient", Color: []string{"#fafbfc", "#fafbfc"}},
		Font: &excelize.Font{Family: "Perpetua", Size: 14},
	})
	headerStyle, err := file.NewStyle(&excelize.Style{
		Alignment: &excelize.Alignment{
			Horizontal: "center",
			Vertical:   "center",
		},
		Border: []excelize.Border{
			{Type: "left", Color: "6e7ea", Style: 1},
			{Type: "top", Color: "e6e7ea", Style: 1},
			{Type: "bottom", Color: "e6e7ea", Style: 1},
			{Type: "right", Color: "e6e7ea", Style: 1},
		},
		Fill: excelize.Fill{Type: "gradient", Color: []string{"#fafbfc", "#fafbfc"}},
		Font: &excelize.Font{Family: "Perpetua", Size: 14},
	})
	if err != nil {
		log.Fatal(err)
		return
	}

	// 竖着
	for _, report := range reports {
		file.SetCellValue(file.GetSheetName(index), "A2", "日期")
		file.SetCellValue(file.GetSheetName(index), "B2", "星期")
		file.SetCellValue(file.GetSheetName(index), "A"+strconv.Itoa(line+2), report.Date)
		file.SetCellValue(file.GetSheetName(index), "B"+strconv.Itoa(line+2), report.Week)
		i := 2
		// 横着
		for _, person := range report.Persons {
			col := colArr[i]
			if line == 1 {
				hCol := colArr[i+3]
				file.MergeCell(file.GetSheetName(index), col+"1", hCol+"1")
				file.SetCellValue(file.GetSheetName(index), col+"1", person.Name+"("+person.EnName+")")
				file.SetCellStyle(file.GetSheetName(index), col+"1", hCol+"1", style)

				file.SetCellStyle(file.GetSheetName(index), col+"2", hCol+"2", style)
				file.SetCellValue(file.GetSheetName(index), col+"2", "上班打卡")
				file.SetCellValue(file.GetSheetName(index), colArr[i+1]+"2", "下班打卡")
				file.SetCellValue(file.GetSheetName(index), colArr[i+2]+"2", "假勤申请")
				file.SetCellValue(file.GetSheetName(index), colArr[i+3]+"2", "备注")
			}
			file.SetCellValue(file.GetSheetName(index), col+strconv.Itoa(line+2), person.Start)
			file.SetCellValue(file.GetSheetName(index), colArr[i+1]+strconv.Itoa(line+2), person.End)
			file.SetCellValue(file.GetSheetName(index), colArr[i+2]+strconv.Itoa(line+2), person.Holiday)
			file.SetCellValue(file.GetSheetName(index), colArr[i+3]+strconv.Itoa(line+2), person.Desc)
			i += 4
		}
		if line <= 2 {
			file.SetRowHeight(file.GetSheetName(index), line, 30)
		}
		file.SetRowHeight(file.GetSheetName(index), line+ex, 25)
		line++
	}
	// 设置列样式
	file.SetColStyle(file.GetSheetName(index), "A:"+maxCol, style)
	file.SetColWidth(file.GetSheetName(index), "A", maxCol, 20)
	// 设置行样式
	file.SetRowStyle(file.GetSheetName(index), 1, 2, headerStyle)

	if err := file.Save(); err != nil {
		log.Fatal(err)
	}
}
